

import thread
import random
from math import *

import game
import integrator



class Spaceship:
    accel = 0.0
    alpha = 0.0
    x = 0.0
    y = 0.0
    theta = 0.0
    u = 0.0
    v = 0.0
    omega = 0.0
    maxalpha =  1.0
    minalpha = -1.0
    maxaccel =  1.0
    minaccel = -1.0
    radius = 1.0;
    def tosubmsg(self):
        return ','.join(map(str,[
                    self.x,
                    self.y,
                    self.theta,
                    self.u,
                    self.v,
                    self.omega]))
    def setAccel(self, val):
        self.accel = val
        if val > self.maxaccel:
            self.accel = self.maxaccel
        if val < self.minaccel:
            self.accel = self.minaccel
        return
    def setAlpha(self, val):
        self.alpha = val
        if val > self.maxalpha:
            self.alpha = self.maxalpha
        if val < self.minalpha:
            self.alpha = self.minalpha
        return
    

def __init__(self, x, y, theta):
    self.x = x
    self.y = y
    self.theta = theta
    return

#Setters-----------
def setaa(ship, accel, alpha):
    #put accel in bounds
    if   (accel < ship.minaccel):
        ship.accel = ship.minaccel
    elif (accel > ship.maxaccel):
        ship.accel = ship.maxaccel
    else:
        ship.accel = accel
    
    #put alpha in bounds
    if   (alpha < ship.minalpha):
        ship.alpha = ship.minalpha
    elif (alpha > ship.maxalpha):
        ship.alpha = ship.maxalpha
    else:
        ship.alpha = alpha
        
    return

def setState(x, y, u, v):
    self.x = x;
    self.y = y;
    self.u = u;
    self.v = v;
    return

#Getters----------------
def getaa(self):
    return self.accel, self.alpha

#-----------------------
class Chaser(Spaceship):
    maxalpha =  1.0
    minalpha = -1.0
    maxaccel =  1.0
    minaccel = -1.0

#-----------------------
class Chasee(Spaceship):
    maxalpha =  1.0
    minalpha = -1.0
    maxaccel =  0.75
    minaccel = -0.75



class Pursuit(game.Game):
    type = 'pursuitv0.0'
    chaser = Chaser()
    chasee = Chasee()
    roledict = {}
    pursuit_started = False
    roundcount = 0
    roundmax = 1000
    hit = False
    
    def __init__(self, name, server=None):
        game.Game.__init__(self, name, server)
        return
    
    def joinhandle(self, name, role):
        '''
        handles a player wanting to join
        '''
        if role == 'observer':
            return True
        if role not in ['chaser','chasee']:
            return False
        if not self.open:
            return False
        nonobservers = [n for n in self.players
                        if self.players[n] != 'observer']
        if len(nonobservers) == 1:
            if self.players[nonobservers[0]] == role:
                return False
            self.open=False
            #if self.pursuit_started:
            #    self.hit = integrator.integratePaths(self.chaser,self.chasee,0.1)
            #else:
            for i in xrange(1):
                self.pursuit_started=True
                self.chaser.x = random.gauss(mu=5.0,sigma=3.0)
                self.chaser.y = random.gauss(mu=5.0,sigma=3.0)
                self.chaser.theta = random.uniform(0,2*pi)
                self.chasee.x = random.gauss(mu=-5.0,sigma=3.0)
                self.chasee.y = random.gauss(mu=-5.0,sigma=3.0)
                self.chasee.theta = random.uniform(0,2*pi)
            self.donerecv.release() #essentially starts the game
        return True
    
    def recvhandle(self, name, message):
        '''
        handles a player's message
        '''
        role = self.players[name]
        if role == 'observer':
            return
        #message = message[1:]
        try:
            accel, alpha = map(float,message.split(','))
        except:
            accel, alpha = (0.0, 0.0)
        rd={'chaser':self.chaser,
            'chasee':self.chasee}
        setaa(rd[role],accel,alpha)
        self.playermsg[name] = message #default, no processing
        return
    
    def sendhandle(self):
        '''
        prepares self.message to be sent to players
        '''
        self.roundcount+=1
        self.hit = integrator.integratePaths(self.chaser,self.chasee,0.1)
        hit = self.hit
        for pname in self.players:
            prole = self.players[pname]
            if   prole == 'chaser':
                if hit:
                    self.message[pname] = '{win}'
                elif self.roundcount >= self.roundmax:
                    self.message[pname] = '{lose}'
                else:
                    self.message[pname] = '{'+','.join(
                        [self.chaser.tosubmsg(),self.chasee.tosubmsg()])+'}'
            elif prole == 'chasee':
                if hit:
                    self.message[pname] = '{lose}'
                elif self.roundcount >= self.roundmax:
                    self.message[pname] = '{win}'
                else:
                    self.message[pname] = '{'+','.join(
                        [self.chasee.tosubmsg(),self.chaser.tosubmsg()])+'}'
            elif prole == 'observer':
                if hit:
                    self.message[pname] = '{hit}'
                elif self.roundcount >= self.roundmax:
                    self.message[pname] = '{miss}'
                else:
                    self.message[pname] = '{'+','.join(
                        [n+','+
                         self.players[n]+','+
                         {'chasee':self.chasee.tosubmsg(),
                          'chaser':self.chaser.tosubmsg()}[
                                self.players[n]]
                         for n in self.players 
                         if self.players[n] in ['chaser','chasee']]
                        )+'}'
        return not hit
    
